//----------------------------------
//--------Punch SWEP--------------
//-----------Made by Luafox---------
//----------------------------------
//---Part of the SMOD Weapons Pack--
//----------------------------------

//if on server
if SERVER then

	//add the file
	AddCSLuaFile("shared.lua");

	//set the hold type
	SWEP.HoldType			= "pistol";

end

//if on client
if CLIENT then

	//set some stuff
	SWEP.PrintName			= "Gordon's Fists";
	SWEP.Author				= "Luafox";
	SWEP.Slot				= 0;
	SWEP.SlotPos			= 9;
	SWEP.Purpose			= "Punch-out!";
	SWEP.Instructions		= "Primary: Fast Punch, Secondary: Strong Punch";
	SWEP.DrawAmmo 		= false;
	SWEP.DrawCrosshair	= false;

	--set the category
	SWEP.Category			= "SMOD";
	
	--selection icon
	SWEP.WepSelectIcon = surface.GetTextureID("weapons/smodpunchicon");

	-- Kill Icon
	if(file.Exists("../materials/weapons/smodpunch_killicon.vmt")) then

		killicon.Add("weapon_punch_smod","weapons/smodpunch_killicon",Color(255,255,255));

	end 

end

//is it spawnable?
SWEP.Spawnable				= true;
SWEP.AdminSpawnable			= false;

//models
SWEP.ViewModel				= "models/weapons/v_punch.mdl";
SWEP.WorldModel				= "";

//more stuff
SWEP.Weight					= 7;
SWEP.AutoSwitchTo			= true;
SWEP.AutoSwitchFrom			= true;
SWEP.PunchDist				= 70;

//primary settings
SWEP.Primary =
{
	ClipSize				= -1,
	DefaultClip				= -1,
	Automatic				= true,
	Ammo					= "none"
}

//secondary settings
SWEP.Secondary =
{
	ClipSize				= -1,
	DefaultClip				= -1,
	Automatic				= true,
	Ammo					= "none"
}

//delays
SWEP.PrimeroDelay = CurTime()
SWEP.SeconderoDelay = CurTime()

//on initialize
function SWEP:Initialize()

	//if on server
	if SERVER then

		//set the hold type
		self:SetWeaponHoldType(self.HoldType);

	end

end

function SWEP:Precache() --preload our sounds
util.PrecacheSound("physics/body/body_medium_impact_hard6.wav")
util.PrecacheSound("physics/body/body_medium_impact_hard4.wav")
util.PrecacheSound("physics/body/body_medium_impact_hard2.wav")
util.PrecacheSound("physics/body/body_medium_impact_hard3.wav")
util.PrecacheSound("physics/body/body_medium_impact_hard1.wav")
util.PrecacheSound("weapons/iceaxe/iceaxe_swing1.wav")
util.PrecacheSound("weapons/slam/throw.wav")
end

--idleanimation controlled by timers
function SWEP:DoIdle(seconds)
	timer.Destroy("PunchIdle")
	timer.Create("PunchIdle", seconds, 3, function() self:SendWeaponAnim(ACT_VM_IDLE); end)
end

--Selfmade trace function to be used in primary and secondary
function SWEP:TraceTrace()
	local pos = self.Owner:GetShootPos()
	local aim = self.Owner:GetAimVector()
	local T = {} --trace table
	T.start = pos --start at players shoot position
	T.endpos = pos + aim * self.PunchDist -- end at players shoot position plus at players aim times the distance of the punch
	T.filter = self.Owner
	local hittrace = util.TraceLine(T) --traceline
		if hittrace.HitNonWorld && hittrace.Entity then -- did we hit something else than the world? did we hit an entity`?
		
	--if the entity is valid and it's not the world and the player holds down the primary fire key then
			if hittrace.Entity:IsValid() && !hittrace.Entity:IsWorld() && self.Owner:KeyDown( IN_ATTACK ) then
				hittrace.Entity:TakeDamage(5, self.Owner) -- hurt the entity
				if hittrace.Entity:IsNPC() then --is it an NPC?
					hittrace.Entity:SetVelocity(hittrace.Entity:GetVelocity() + aim * self.PunchDist * 2) --knock them back
				else -- is it something else?
					local Phys = hittrace.Entity:GetPhysicsObject() 
					if Phys:IsValid() then --is it valid?
						Phys:ApplyForceCenter(Phys:GetMass() * self.PunchDist * aim * 1.2) --knock it away
					end
				end
				
				local Sound =
				{
				"physics/body/body_medium_impact_hard6.wav",
				"physics/body/body_medium_impact_hard4.wav",
				"physics/body/body_medium_impact_hard2.wav"
				}
				self.Weapon:EmitSound(Sound[math.random(1,3)]) -- random hit sounds
			end
			
	--if the entity is valid and it's not the world and the player holds down the secondary fire key then
			if hittrace.Entity:IsValid() && !hittrace.Entity:IsWorld() && self.Owner:KeyDown( IN_ATTACK2 ) then
				hittrace.Entity:TakeDamage(10, self.Owner) -- hurt the entity
				if hittrace.Entity:IsNPC() then --is it an NPC?
					hittrace.Entity:SetVelocity(hittrace.Entity:GetVelocity() + aim * self.PunchDist * 2.5) --knock them back
				else -- is it something else?
					local Phys = hittrace.Entity:GetPhysicsObject()
					if Phys:IsValid() then -- is it valid?
						Phys:ApplyForceCenter(Phys:GetMass() * self.PunchDist * aim * 1.8) --knock it away
					end
				end
				
				local Sound =
				{
				"physics/body/body_medium_impact_hard6.wav",
				"physics/body/body_medium_impact_hard4.wav",
				"physics/body/body_medium_impact_hard2.wav"
				}
				self.Weapon:EmitSound(Sound[math.random(1,3)]) -- random hit sounds
				
			end
			
		elseif hittrace.HitWorld then -- if we hit the world
				local Sound =
				{
				"physics/body/body_medium_impact_hard1.wav",
				"physics/body/body_medium_impact_hard3.wav"
				}
				self.Weapon:EmitSound(Sound[math.random(1,2)]) -- random hit sounds
		
		else  --if we miss				
				if self.Owner:KeyDown( IN_ATTACK ) then
					self.Weapon:EmitSound(Sound("weapons/iceaxe/iceaxe_swing1.wav"))
				elseif self.Owner:KeyDown( IN_ATTACK2 ) then
					self.Weapon:EmitSound(Sound("weapons/slam/throw.wav"))
				end
		end
end

--Primary attack
function SWEP:PrimaryAttack()
	if self.PrimeroDelay < CurTime() && self.SeconderoDelay < CurTime() then
		self.PrimeroDelay = CurTime()+ 0.34
		
	self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
	self:TraceTrace() --call our trace function
	
	self.Owner:ViewPunch(Angle(math.Rand(-1.5,1.5),math.Rand(-1.5,1.5),math.Rand(-1.5,1.5))); --knock the view
	
	self:DoIdle(3) -- run our idle animation
	end

end

--Secondary attack
function SWEP:SecondaryAttack()
	if self.SeconderoDelay < CurTime() && self.PrimeroDelay < CurTime() then
		self.SeconderoDelay = CurTime()+ 0.6
		
	self.Weapon:SendWeaponAnim(ACT_VM_SECONDARYATTACK)
	self:TraceTrace() --call our trace function
	
	self.Owner:ViewPunch(Angle(math.Rand(-2.5,2.5),math.Rand(-2.5,2.5),math.Rand(-2.5,2.5))); --knock the view
	
	self:DoIdle(3) -- run our idle animation
	end
	
end

--when reloading
function SWEP:Reload()
	return false
end

--when we deploy
function SWEP:Deploy()

	//run the deploy animation
	self.Weapon:SendWeaponAnim(ACT_VM_DRAW);
	self:DoIdle(3) -- run our idle animation

	//and return
	return true;

end

--when we holster
function SWEP:Holster()
	//destroy the timer so it's not there the next time we pull out the weapon
	timer.Destroy("PunchIdle");

	//and return
	return true;
end 

--kill the timer if the player died, doesn't work, but the idea is right
function PlayerDied()
		timer.Destroy("PunchIdle");
end
hook.Add("PlayerDeath","killtimers",PlayerDied)   